<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">  <!-- Use Chrome Frame in IE -->
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
    <meta name="description" content="Clamp positions to a 3D tileset surface.">
    <meta name="cesium-sandcastle-labels" content="Development">
    <title>Cesium Demo</title>
    <script type="text/javascript" src="../Sandcastle-header.js"></script>
    <script type="text/javascript" src="../../../ThirdParty/requirejs-2.1.20/require.js"></script>
    <script type="text/javascript">
    require.config({
        baseUrl : '../../../Source',
        waitSeconds : 60
    });
    </script>
</head>
<body class="sandcastle-loading" data-sandcastle-bucket="bucket-requirejs.html">
<style>
    @import url(../templates/bucket.css);
</style>
<div id="cesiumContainer" class="fullSize"></div>
<div id="loadingOverlay"><h1>Loading...</h1></div>
<script id="cesium_sandcastle_script">
function startup(Cesium) {
    'use strict';
//Sandcastle_Begin
// Power Plant design model provided by Bentley Systems
var viewer = new Cesium.Viewer('cesiumContainer', {
    contextOptions: {
        webgl: {
            preserveDrawingBuffer: true
        }
    }
});
var scene = viewer.scene;
var camera = scene.camera;

// camera frustum for overhead picking
var pickFrustum = new Cesium.OrthographicFrustum();
pickFrustum.near = 0.001;
pickFrustum.far = 1000.0;
pickFrustum.width = 1000.0;
pickFrustum.aspectRatio = scene.drawingBufferWidth / scene.drawingBufferHeight;

var canvas = scene.canvas;
var lastFrame = new Image();
lastFrame.width = canvas.width;
lastFrame.height = canvas.height;
lastFrame.style = "position: absolute; left: 0; top: 0;";
canvas.parentNode.appendChild(lastFrame);

var samplePosition = Cesium.Cartesian3.fromDegrees(-76.360485, 34.949670, 0);

var tileset = new Cesium.Cesium3DTileset({ url: Cesium.IonResource.fromAssetId(3837) });
tileset.readyPromise.then(function(tileset) {
    scene.primitives.add(tileset);
    viewer.zoomTo(tileset, new Cesium.HeadingPitchRange(0.5, -0.2, tileset.boundingSphere.radius * 4.0));

    getTilesetDepthPick(tileset, samplePosition)
        .then(function(result) {
            viewer.entities.add({
                position: result,
                point: {
                    pixelSize: 15,
                    color: Cesium.Color.WHITE
                },
                label: {
                    text: 'Point',
                    fillColor: Cesium.Color.WHITE,
                    pixelOffset: new Cesium.Cartesian2(0.0, -30.0)
                }
            });
        });

}).otherwise(function(error) {
    console.log(error);
});

function getTilesetDepthPick(tileset, position) {
    var promise = Cesium.when.defer();

    // Wait for tileset to complete load
    var removeTilesLoadedListener = tileset.allTilesLoaded.addEventListener(function() {
        // Save current camera values
        var cameraFrustum = camera.frustum;
        var cameraPosition = camera.position;
        var cameraDirection = camera.direction;
        var cameraUp = camera.up;

        // Configure pick camera options for position
        var boundingSphere = tileset.boundingSphere;
        var normal = scene.globe.ellipsoid.geodeticSurfaceNormal(position);
        var offset = Cesium.Cartesian3.multiplyByScalar(normal, boundingSphere.radius * 3.0, new Cesium.Cartesian3());
        var origin = Cesium.Cartesian3.add(scene.globe.ellipsoid.scaleToGeocentricSurface(position), offset, new Cesium.Cartesian3());

        // Add last frame placeholder, render and then pick position with depth
        var removePreRenderListener = scene.postUpdate.addEventListener(function() {
            duplicateLastFrame();

            // Restore original camera values
            camera.frustum = pickFrustum;
            camera.position = origin;
            camera.direction = Cesium.Cartesian3.negate(normal, new Cesium.Cartesian3());
            camera.up = Cesium.Cartesian3.normalize(Cesium.Cartesian3.cross(Cesium.Cartesian3.UNIT_Y, normal, new Cesium.Cartesian3()), new Cesium.Cartesian3());

            var removePostRenderListener = scene.postRender.addEventListener(function() {
                var location = scene.pickPosition(new Cesium.Cartesian2(
                    scene.drawingBufferWidth / 2.0,
                    scene.drawingBufferHeight / 2.0
                ));

                camera.frustum = cameraFrustum;
                camera.position = cameraPosition;
                camera.direction = cameraDirection;
                camera.up = cameraUp;
                removePreRenderListener();

                // Remove frame placeholder after new frame has been rendered
                var removeOverlayListener = scene.postRender.addEventListener(function() {
                    lastFrame.style.display = 'none';
                    removeOverlayListener();
                });

                promise.resolve(location);
                removePostRenderListener();

                return true;
            });
        });

        removeTilesLoadedListener();
    });

    return promise;
}

function duplicateLastFrame() {
    lastFrame.src = canvas.toDataURL('image/png');
    lastFrame.style.display = 'block';
}

//Sandcastle_End
Sandcastle.finishedLoading();
}
if (typeof Cesium !== "undefined") {
    startup(Cesium);
} else if (typeof require === "function") {
    require(["Cesium"], startup);
}
</script>
</body>
</html>
